<?php
/**
 * Created by PhpStorm.
 * User: wangsentao
 * Date: 2017/11/1
 * Time: 上午11:01
 */

namespace app\common\Utils;


class RedisPk
{
    private static $handler = null;
    private static $_instance = null;

    private function __construct($options = [])
    {
        $redis_conf = [
            'host' => '139.196.110.120',
            'port' => 6379,
            'password' => '',
            'select' =>2,
            'timeout'    => 3,
            'expire'     => 0,
            'persistent' => false,
            'prefix'     => '',
        ];

        if (!extension_loaded('redis')) {
            throw new \BadFunctionCallException('not support: redis');      //判断是否有扩展
        }

        $func = $redis_conf['persistent'] ? 'pconnect' : 'connect';     //长链接
        self::$handler = new \Redis;
        self::$handler->$func($redis_conf['host'], $redis_conf['port'], $redis_conf['timeout']);

        if ('' != $redis_conf['password']) {
            self::$handler->auth($redis_conf['password']);
        }
        //self::$handler->setOption(\Redis::OPT_PREFIX, '');

        if (0 != $redis_conf['select']) {
            self::$handler->select($redis_conf['select']);
        }
    }

    /**
     * @return RedisPk|null null object
     */
    public static function getInstance()
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * 禁止外部克隆
     */
    public function __clone()
    {
        trigger_error('Clone is not allowd!', E_USER_ERROR);
    }

    /**
     * @param $key 键
     * @param $value 值
     * @param int $exprie 过期时间 0:永不过期
     * @return bool
     */
    public static function set($key, $value, $exprie = 0)
    {
        if ($exprie == 0) {
            $set = self::$handler->set($key, $value);
        } else {
            $set = self::$handler->setex($key, $exprie, $value);
        }
        return $set;
    }

    /**
     * 键值获取
     * @param $key 键值
     * @return mixed
     */
    public static function get($key)
    {
        $fun = is_array($key) ? 'Mget' : 'get';
        return self::$handler->{$fun}($key);
    }

    /**
     * 获取key的长度
     * @param $key $key
     * @return int
     */
    public static function lLen($key)
    {
        return self::$handler->lLen($key);
    }

    /**
     * 将一个或多个值插入到列表头部
     * @param $key
     * @param $value
     * @return int
     */
    public static function LPush($key, $value)
    {
        return self::$handler->lPush($key, $value);
    }

    /**
     * 移出并获取列表的第一个元素
     * @param $key
     * @return string
     */
    public static function lPop($key)
    {
        return self::$handler->lPop($key);
    }

    /**
     * redis 哈希操作
     * @param $name
     * @param $key
     * @param $value
     * @return int
     */
    public static function hset($name, $key, $value)
    {
        if (is_array($value)) {
            return self::$handler->hset($name, $key, serialize($value));
        }
        return self::$handler->hset($name, $key, $value);
    }

    /**
     * 哈希获取
     * @param $name
     * @param null $key
     * @param bool $serialize
     * @return array|string
     */
    public static function hget($name, $key = null, $serialize = true)
    {
        if ($key) {
            $row = self::$handler->hget($name, $key);
            if ($row && $serialize) {
                unserialize($row);
            }
            return $row;
        }
        return self::$handler->hgetAll($name);
    }

    /**
     * 删除 单键 缓存
     * @param $key
     * @return int
     */
    public static function clear($key)
    {
        if ($key) {
            return self::$handler->delete($key);
        }
        return;
    }

    /**
     * 删除hash表中指定字段 ,支持批量删除
     * @param string $key 缓存key
     * @param string $field 字段
     * @return int
     */
    public static function hdel($key, $field)
    {
        $fieldArr = explode(',', $field);
        $delNum = 0;

        foreach ($fieldArr as $row) {
            $row = trim($row);
            $delNum += self::$handler->hDel($key, $row);
        }

        return $delNum;
    }
}